#include <iostream>
#include <string>
#include <string.h>
#include <strings.h>
#include <sys/types.h>          
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "log.hpp"


uint16_t defaultport = 8080;
static std::string defaultip = "0.0.0.0";
static const int gbacklog = 5;

namespace TcpServer
{
    
    class Server
    {
    public:
           Server(const uint16_t& Serverport = defaultport,const std::string& Serverip = defaultip)
           :_Serverport(Serverport),_Serverip(Serverip),_sockfd(-1)
           {}

           void init()
           {
                //穿件套接字，打开文件描述符
                _sockfd = socket(AF_INET,SOCK_STREAM,0);
                if(_sockfd == -1)
                {
                    //打印错误日志，返回
                    logmessage("fatal",getpid(),"socket failed");
                    exit(1);
                }
                //打印成功日志
                logmessage("sucess",getpid(),"socket sucess");
                
                //开始建立bind链接
                struct sockaddr_in address;
                bzero(&address,sizeof(address));
                address.sin_family = AF_INET;
                address.sin_port = htons(_Serverport);
                address.sin_addr.s_addr = INADDR_ANY;

                
                int n  = bind(_sockfd,(struct sockaddr*)&address,sizeof(address));
                if(n == -1)
                {
                    logmessage("fatal",getpid(),"bind failed");
                    exit(2);
                }
                logmessage("sucess",getpid(),"bind sucess");

                //开始监听
                
                 n  =  listen( _sockfd, gbacklog);
                 if( n < 0)
                 {
                    logmessage("fatal",getpid(),"listen failed");
                    exit(3);
                 }
                 logmessage("sucess",getpid(),"listen suscess");
           }

           void start()
           {
                //正式开始工作
                // 1 . accpet建立接收客户端建立新链接
                 while(1)
                 {
                    struct sockaddr_in address;
                    bzero(&address,sizeof(address));
                    socklen_t length = sizeof(address);
                    int sock  = accept(_sockfd,(struct sockaddr*)&address,&length);

                    if(sock == -1)
                    {
                        logmessage("errno",getpid(),"notarget");
                        continue;
                    }
                    logmessage("sucess",getpid(),"accept sucess");
                    std::cout << "socketfd ：" << sock << std::endl;
                    
                    //建立链接成功，可以开始通信了
                    serverio(sock);
                    close(sock);
                 }

           }

           void serverio(int sock)
           {
                //为该客户提供服务
                char buffer[1024];
                while(1)
                {
                    //接收信息
                    ssize_t n= read(sock, buffer,sizeof buffer - 1);
                    std::cout << "buffer = " << buffer << std::endl;

                    if(n > 0)
                    {
                        //read完成后要给对方回信息
                       // buffer[strlen (buffer) - 1 ] = 0;
                        //std::string response = "我是服务器，好的我现在收到了你的信息";
                        buffer[n] = 0;

                         n =  write(sock,buffer,sizeof buffer);
                         if( n == - 1)
                         {
                            logmessage("fatal",getpid(),"write failed");
                            exit(4);
                         }
                         logmessage("write",getpid(),"write sucess");
                    }
                    else if(n == 0)
                    {
                        //说明客户端已经退出，我也可以退出了
                        std::cout << "Cilent quie me too!" << std::endl;
                        break;
                    }
                    //发送信息
                }
           }
    private:
       std::string _Serverip;
       uint16_t _Serverport;
       int _sockfd;
    };
}